/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ds_semetralka;

import entities.Faculty;
import entities.Professor;
import entities.Subject;

import java.util.List;

import javax.persistence.LockModeType;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall;


/**
 *
 * @author Admin
 */
public class ProfessorInterface extends Interface {

    private Professor professor;

    public ProfessorInterface() {
        emf = Persistence.createEntityManagerFactory("persistence");
        em = emf.createEntityManager();
        tx = em.getTransaction();
    }

    public ProfessorInterface(Long professorId) {
        emf = Persistence.createEntityManagerFactory("persistence");
        em = emf.createEntityManager();
        tx = em.getTransaction();

        this.professor = em.find(Professor.class, professorId);
    }

    public boolean setProfessor(Long id) {
        this.professor = em.find(Professor.class, id);

        if (professor == null) {
            return false;
        }

        return true;
    }

    public Professor getProfessor() {
        return professor;
    }

    @Override
    public List<Subject> getAllSubjects() {
        Query q = em.createNamedQuery("Subject.findAll");

        return q.getResultList();
    }

    @Override
    public List<Faculty> getAllFaculties() {
        CriteriaBuilder critBuild = em.getCriteriaBuilder();
        CriteriaQuery<Faculty> query = critBuild.createQuery(Faculty.class);

        Root<Faculty> from = query.from(Faculty.class);
        query.select(from);
        try {
            return em.createQuery(query).getResultList();
        } catch (NoResultException e) {
            System.out.println("No result");
            return null;
        }

    }

    @Override
    public List<Subject> getSubjectsFromFaculty(Faculty faculty) {
        Query q = em.createNamedQuery("Subject.findbyFaculty");

        q.setParameter("faculty", faculty);

        return q.getResultList();
    }

    @Override
    public List<Subject> getSubjectsFromFaculty(Long facultyId) {
        Query q = em.createNamedQuery("Subject.findbyFaculty");
        Faculty faculty = em.find(Faculty.class, facultyId);

        if (faculty == null) {
            System.out.println("Faculty does not exist");
            return null;
        }

        q.setParameter("faculty", faculty);

        return q.getResultList();
    }

    public void createSubject(Long facultyId, Subject subject) {

        Faculty faculty = em.find(Faculty.class, facultyId);

        tx.begin();

        faculty.addSubject(subject);
        subject.setFaculty(faculty);
        subject.setSupervisor(professor);
        professor.addSupervisedSubject(subject);

        em.persist(professor);
        em.persist(subject);
        em.persist(faculty);
        tx.commit();
    }

    public void addSubject(Long subjectId) {
        try {
            tx.begin();
            Subject subject = em.find(Subject.class, subjectId, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

            if (subject == null) {
                System.out.println("Subject does not exist.");
                return;
            }


            if (!subject.getProfessors().contains(professor)) {
                professor.addSubject(subject);
                subject.addProfessor(professor);
                System.out.println("Professor " + professor + " is now teaching " + subject);
                em.persist(professor);
                em.persist(subject);

            } else {
                System.out.println("Already teaching this subject.");
                tx.rollback();
            }
            tx.commit();

        } catch (OptimisticLockException ex) {
            System.out.println("Trying to add locked subject");
            tx.rollback();
        }
    }

    public List<Subject> getProfessorsSubjects() {
        return professor.getSubjects();
    }

    public List<Subject> getSupervisedSubjects() {
        return professor.getSupervisedSubjects();
    }
    
    public Boolean checkMaxStudents(long subjectId) {
        Query query = em.createNativeQuery("select issubjectfull("+ subjectId + ")");
        
        try {
                Boolean result = (Boolean) query.getSingleResult();
                return result;
        } catch (NonUniqueResultException e) {
                System.out.println("Vraceno vice vysledku.");
                return null;
        }
    } 
}
